home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / human interface toolbox / romresourcedump / romresourcedump.p < prev    next >
Encoding:
Text File  |  2000-06-23  |  7.5 KB  |  234 lines

  1. {
  2.     File:        ROMResourceDump.p
  3.  
  4.     Contains:    This little utility copies all of the resources in the Macintosh’s ROM into a file called 
  5.                     “ROM Resource Dump File”.  This is useful for the insanely curious, those with a professional 
  6.                     “need to know” (like DTS engineers), and as a trivial Resource Manager sample.
  7.  
  8.                     The supplied source code compiles with Metrowerks Pascal from CodeWarrior 9.
  9.  
  10.                     Some notes:
  11.  
  12.                     1. When you run this program on some older machines it will create a resource file that 
  13.                     ResEdit reports as corrupt.  This is not my fault!  ResEdit is complaining because 
  14.                     the file contains two resources with the same type and ID.  The program does this 
  15.                     because both resources exist in the ROM on that machine.  *sigh*
  16.                     2. The program makes heavy use of Metrowerks Pascal’s console and the ostrich error checking 
  17.                     algorithm.  Call me slack (–:
  18.                        3. Efficiency was not the goal of this program.  I call UpdateResFile religiously while 
  19.                         creating the output file, which doesn’t make it any faster.
  20.  
  21.     Written by:     
  22.  
  23.     Copyright:    Copyright © 1984-1999 by Apple Computer, Inc., All Rights Reserved.
  24.  
  25.                 You may incorporate this Apple sample source code into your program(s) without
  26.                 restriction. This Apple sample source code has been provided "AS IS" and the
  27.                 responsibility for its operation is yours. You are not permitted to redistribute
  28.                 this Apple sample source code as "Apple sample source code" after having made
  29.                 changes. If you're going to re-distribute the source, we require that you make
  30.                 it clear in the source that the code was descended from Apple sample source
  31.                 code, but that you've made changes.
  32.  
  33.     Change History (most recent first):
  34.                 8/9/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  35.                 
  36.  
  37.  
  38. }
  39. program ROMResourceDump;
  40.  
  41.     uses
  42.         Types,
  43.         Memory,
  44.         LowMem,
  45.         Files,
  46.         Resources;
  47.  
  48.  
  49.         procedure CopyROMResource(romResourceH : Handle; destRefnum : integer);
  50.             (*    This routine copies a specific ROM resource into the resource file
  51.                     denoted by destRefnum.  Any error conditions get written to
  52.                     the console.
  53.  
  54.                     The main complications are:
  55.                         
  56.                         1.    Have to call LMSetROMMapInsert even for GetResInfo.
  57.                                 
  58.                         2.    Have to copy the resources from out of the ROM before
  59.                                 adding them into the destination resource file.
  60.                                 
  61.                         3.    Have to deal with memory issues, ie we don't want to fill
  62.                                 up our application heap with resources and then run out of
  63.                                 memory.
  64.                     
  65.             *)
  66.             var
  67.                 err : OSStatus;
  68.                 err2 : OSStatus;
  69.  
  70.                 romResourceType : ResType;
  71.                 romResourceID : integer;
  72.                 romResourceName : Str255;
  73.                 romResourceSize : longint;
  74.         begin
  75.             (*    Get lots of information about the resource.  You have to set ROMMapInsert,
  76.                     even for a simple call like GetResInfo.  If you don't do this, things just
  77.                     don't work properly.
  78.             *)
  79.             LMSetROMMapInsert(-1);
  80.             GetResInfo(romResourceH, romResourceID, romResourceType, romResourceName);
  81.             romResourceSize := GetHandleSize(romResourceH);
  82.  
  83.             writeln('    Resource ''', romResourceType, ''' ID=', romResourceID:1, ' size = ', romResourceSize:1, 
  84.                             ' "', romResourceName, '"');
  85.             
  86.             err := HandToHand(romResourceH);
  87.             if err = noErr then begin
  88.                 UseResFile(destRefnum);
  89.                 
  90.                 AddResource(romResourceH, romResourceType, romResourceID, romResourceName);
  91.                 err := ResError;
  92.                 
  93.                 (* Have to call UpdateResFile before calling ReleaseResource.  This allows
  94.                     the Resource Manager to actually dispose of the memory used by the resource
  95.                     because it's already been written to a file.  If you do this the other
  96.                     way, the Resource Manager hangs on to the new resource pending a call
  97.                     to UpdateResFile, but then doesn't remember to release it when it gets
  98.                     one.
  99.                 *)
  100.                 UpdateResFile(destRefnum);
  101.                 err2 := ResError;
  102.                 if err = noErr then begin
  103.                     err := err2;
  104.                 end; (* if *)
  105.                 
  106.                 ReleaseResource(romResourceH);
  107.                 
  108.                 UseResFile(0);
  109.             end; (* if *)
  110.  
  111.             if err <> noErr then begin
  112.                 writeln('    ••• error writing resource ', err:1);
  113.             end; (* if *)
  114.     end; (* CopyROMResource *)
  115.  
  116.  
  117.     function DumpROMResourcesToResourceFile(destRefnum : integer) : OSStatus;
  118.         (* This routine dumps all of the resources in the ROM into the resource file
  119.                 whose reference number is destRefnum.  The basic implementation
  120.                 is a standard:
  121.                 
  122.                     for type = 1 to count of types
  123.                         for index = 1 to count of resources in this type
  124.                             get indexed resource
  125.                                 put it our file
  126.                 
  127.                 This technique normally works for normal resource files but, as long
  128.                 as you set ROMMapInsert before calling the Resource Manager, the
  129.                 technique works equally well for ROM resources.
  130.                 
  131.                 This routine doesn't deal with errors particularly well, especially
  132.                 out of memory errors.
  133.         *)
  134.         var
  135.             saveResFile : integer;
  136.             
  137.             typeCount : integer;
  138.             typeIndex : integer;
  139.             thisType : ResType;
  140.             resourceCount : integer;
  141.             resourceIndex : integer;
  142.             
  143.             foundResourceH : Handle;
  144.     begin
  145.         saveResFile := CurResFile;
  146.         UseResFile(0);
  147.  
  148.         (* Count the number of resource types in the ROM. *)            
  149.         LMSetROMMapInsert(-1);
  150.         typeCount := Count1Types;
  151.         writeln('Number of types = ', typeCount:1);
  152.         
  153.         (* Iterate through each of the types. *)
  154.         for typeIndex := 1 to typeCount do begin
  155.  
  156.             (* Get the information for this type. *)
  157.             LMSetROMMapInsert(-1);
  158.             Get1IndType(thisType, typeIndex);
  159.                         
  160.             (* Count the number of resources of this type in the ROM. *)            
  161.             LMSetROMMapInsert(-1);
  162.             resourceCount := Count1Resources(thisType);
  163.             writeln('  Number of resources for type ''', thisType, ''' = ', resourceCount:1);
  164.  
  165.             (* Iterate through each of the resources. *)
  166.             for resourceIndex := 1 to resourceCount do begin
  167.                 
  168.                 (* Get this resource. *)
  169.                 LMSetROMMapInsert(-1);
  170.                 LMSetTmpResLoad(-1);
  171.                 foundResourceH := Get1IndResource(thisType, resourceIndex);
  172.                 
  173.                 if foundResourceH = nil then begin
  174.                     writeln('   ••• Could not get resource ''', thisType, ''' index ', resourceIndex:1);
  175.                 end else begin
  176.                     (* Copy the resource into the destination resource file. *)
  177.                     CopyROMResource(foundResourceH, destRefnum);
  178.                 end; (* if *)
  179.             end; (* for *)
  180.         end; (* for *)
  181.         
  182.         UseResFile(saveResFile);
  183.         
  184.         DumpROMResourcesToResourceFile := noErr;
  185.     end; (* DumpROMResourcesToResourceFile *)
  186.     
  187.     
  188.     (*    The main line simply opens a unique destination resource file
  189.             and then calls DumpROMResourcesToResourceFile to copy the ROM
  190.             resources into it.
  191.     *)
  192.     
  193.     const
  194.         kOutputFileName = 'ROM Resource Dump File';
  195.         
  196.     var
  197.         err : OSStatus;
  198.         junk : OSStatus;
  199.         fcbPBlock : FCBPBRec;
  200.         retryCount : integer;
  201.         dumpFileSpec : FSSpec;
  202.         dumpFileRefnum : integer;
  203. begin
  204.     writeln('ROMResourceDump');
  205.     
  206.     fcbPBlock.ioRefNum := CurResFile;
  207.     err := PBGetFCBInfoSync(@fcbPBlock);
  208.  
  209.     if err = noErr then begin
  210.         junk := FSMakeFSSpec(fcbPBlock.ioVRefNum, fcbPBlock.ioFCBParID, kOutputFileName, dumpFileSpec);
  211.         retryCount := 0;
  212.         repeat
  213.             FSpCreateResFile(dumpFileSpec, 'RSED', 'rsrc', 0);
  214.             err := ResError;
  215.             if err <> noErr then begin
  216.                 retryCount := retryCount + 1;
  217.                 junk := FSMakeFSSpec(fcbPBlock.ioVRefNum, fcbPBlock.ioFCBParID, stringof(kOutputFileName, ' ', retryCount:1), dumpFileSpec);
  218.             end; (* if *)
  219.         until (err = noErr) or (retryCount > 10);
  220.     end; (* if *)
  221.     
  222.     if err = noErr then begin
  223.         dumpFileRefnum := FSpOpenResFile(dumpFileSpec, fsRdWrPerm);
  224.         err := ResError;
  225.     end; (* if *)
  226.     
  227.     if err = noErr then begin
  228.         err := DumpROMResourcesToResourceFile(dumpFileRefnum);
  229.         CloseResFile(dumpFileRefnum);
  230.     end; (* if *)
  231.     
  232.     writeln('Done. Press command-Q to Quit.');
  233. end. (* ROMResourceDump *)
  234.